package desktop.core.playfield;

import pulpcore.Stage;
import pulpcore.animation.Timeline;
import pulpcore.animation.event.AddSpriteEvent;
import pulpcore.animation.event.RemoveSpriteEvent;
import pulpcore.scene.Scene2D;
import pulpcore.sprite.ImageSprite;
import desktop.conf.BarConf;
import desktop.core.bar.Bar;
import desktop.core.bar.BarController;
import desktop.playerguide.GameOverScene;

public class PlayFieldViewDoubleBar extends PlayFieldViewAbstract {
	protected Bar leftCurrentBar;
	protected Bar leftNextBar;
	protected BarController leftBarController;
	protected Bar rightCurrentBar;
	protected Bar rightNextBar;
	protected BarController rightBarController;

	public PlayFieldViewDoubleBar(double x, double y, double width,
			double height, PlayFieldModel playFieldModel,
			BarController leftBarController, BarController rightBarController) {
		this(x, y, width, height, playFieldModel, leftBarController,
				rightBarController, "PlayingField.jpg");
	}

	public PlayFieldViewDoubleBar(double x, double y, double width,
			double height, PlayFieldModel playFieldModel,
			BarController leftBarController, BarController rightBarController,
			String background) {
		super(x, y, width, height, playFieldModel);

		timeline = new Timeline();
		timeline.addEvent(new AddSpriteEvent(this, new ImageSprite(background,
				0, 0, this.width.get(), this.height.get()), 0));
		((Scene2D) Stage.getScene()).addTimeline(timeline);

		this.leftCurrentBar = this.receiveNextBar(0);

		timeline = new Timeline();
		timeline.addEvent(new AddSpriteEvent(this, leftCurrentBar, 0));
		((Scene2D) Stage.getScene()).addTimeline(timeline);

		this.leftNextBar = this.receiveNextBar(0);
		this.leftBarController = leftBarController;

		this.rightCurrentBar = this.receiveNextBar(this.playFieldModel
				.getColumn()
				- BarConf.getColumn());

		timeline = new Timeline();
		timeline.addEvent(new AddSpriteEvent(this, rightCurrentBar, 0));
		((Scene2D) Stage.getScene()).addTimeline(timeline);

		this.rightNextBar = this.receiveNextBar(this.playFieldModel.getColumn()
				- BarConf.getColumn());
		this.rightBarController = rightBarController;
	}

	public Bar getLeftNextBar() {
		return leftNextBar;
	}

	public Bar getRightNextBar() {
		return rightNextBar;
	}

	@Override
	public void update(int elapsedTime) {

		controlSpeed(elapsedTime);

		try {
			if (this.reachesBottom(this.leftCurrentBar)) {
				this.applySquaresFromBar(this.leftCurrentBar);
				this.timeToControlBar += this.applySquareElimination();

				timeline = new Timeline();
				timeline.add(new RemoveSpriteEvent(this, leftCurrentBar, 0));
				timeline.add(new AddSpriteEvent(this, leftNextBar, 0));
				((Scene2D) Stage.getScene()).addTimeline(timeline);

				this.leftCurrentBar = this.leftNextBar;
				this.leftNextBar = this.receiveNextBar(0);
			}
			controlCurrentBar(leftCurrentBar, leftBarController, elapsedTime);

			if (this.reachesBottom(this.rightCurrentBar)) {
				this.applySquaresFromBar(this.rightCurrentBar);
				this.timeToControlBar += this.applySquareElimination();

				timeline = new Timeline();
				timeline.add(new RemoveSpriteEvent(this, rightCurrentBar, 0));
				timeline.add(new AddSpriteEvent(this, rightNextBar, 0));
				((Scene2D) Stage.getScene()).addTimeline(timeline);

				this.rightCurrentBar = this.rightNextBar;
				this.rightNextBar = this.receiveNextBar(this.playFieldModel
						.getColumn()
						- BarConf.getColumn());
			}
			controlCurrentBar(rightCurrentBar, rightBarController, elapsedTime);
		} catch (ArrayIndexOutOfBoundsException e) {
			Stage.pushScene(new GameOverScene(getPointsTotally()));
		}

	}

	@Override
	protected boolean canMoveLeft(Bar bar) {
		return (!this.isLeftEdge(bar)) && (!this.isLeftIntersecs(bar))
				&& (!this.isLeftCollision(bar, rightCurrentBar))
				&& (!this.isLeftCollision(bar, leftCurrentBar));
	}

	@Override
	protected boolean canMoveRight(Bar bar) {
		return (!this.isRightEdge(bar)) && (!this.isRightIntersecs(bar))
				&& (!this.isRightCollision(bar, rightCurrentBar))
				&& (!this.isRightCollision(bar, leftCurrentBar));
	}

	/** 和另外的bar是否相撞 **/
	private boolean isLeftCollision(Bar bar, Bar anotherBar) {
		double xTopCheck = bar.getXLeftTop() - bar.getWidthUnit() / 2;
		double yTopCheck = bar.getYLeftTop();
		double xBottomCheck = bar.getXLeftBottom() - bar.getWidthUnit() / 2;
		double yBottomCheck = bar.getYLeftBottom();
		boolean returnValue = (anotherBar.containsPoint(xTopCheck, yTopCheck))
				|| (anotherBar.containsPoint(xBottomCheck, yBottomCheck));
		return returnValue;
	}

	private boolean isRightCollision(Bar bar, Bar anotherBar) {
		double xTopCheck = bar.getXRightTop() + bar.getWidthUnit() / 2;
		double yTopCheck = bar.getYRightTop();
		double xBottomCheck = bar.getXRightBottom() + bar.getWidthUnit() / 2;
		double yBottomCheck = bar.getYRightBottom();
		boolean returnValue = (anotherBar.containsPoint(xTopCheck, yTopCheck))
				|| (anotherBar.containsPoint(xBottomCheck, yBottomCheck));
		return returnValue;
	}
}